package analiseSintatica.Regras.Expressoes;

import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.Regras.*;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.ErroSemantico;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import java.util.LinkedList;

/**
 *
 * @author linton
 * @author nathy
 */
public class RegraExpressao extends Regra {

    protected static Regra instancia;


    RegraLogicaE Regralogica_e = RegraLogicaE.getInstance();
    protected String estrutura = "<logica_e> {|| <logica_e>}";



    /**
     * Construtor privado necessario ao singleton
     */
    private RegraExpressao() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraExpressao getInstance() {
        if (instancia == null) {
            instancia = new RegraExpressao();
        }
        return (RegraExpressao) instancia;
    }
    

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        TiposSemanticos tipoReturn = new TiposSemanticos();

        
        TiposSemanticos tipos1 = RegraLogicaE.getInstance().analisar(listaTokens);
        tipoReturn = tipos1;

        while(listaTokens.getFirst().getLexema().equals("||")){

        	reconheceLexema(listaTokens, "operador_logico", "||", estrutura);
        	
            TiposSemanticos tipos2 = RegraLogicaE.getInstance().analisar(listaTokens);
            
            if(tipoReturn != null && tipos2 != null){
            	//SE EXISTE OPERADOR ||,AMBAS TEM QUE SER BOOLEAN
                int linha = tipos2.getFirst().getLinha();
                if(!(tipos2.getFirst().getNomeTipo().equals("boolean")&&
                     tipoReturn.getFirst().getNomeTipo().equals("boolean"))){
                	AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Expressao deve ser booleana",linha));
                	tipoReturn =  null;
                }
            }
            else{
            	tipoReturn = null;
            }
          }       
        
        return tipoReturn;
    }

    
    

    @Override
    protected void setPrimeiro() {
        this.primeiro =  RegraLogicaE.getInstance().getPrimeiro();
    }

    
}
